<template>
  <div>
    <div class="flex justify-between pt-5 pl-10 pr-10 pb-5" style="background-color: #f7f8fa">
      <div>
        <i class="el-icon-warning" style="color: #fc4541"></i>
        <span class="ft-12 ml-5">如有颜色、尺寸等多种规格，请添加商品规格</span>
        <el-button class="ml-10" type="text"> 查看示例 </el-button>
      </div>
      <div>
        <el-button type="primary" :disabled="skuList.length >= 2" @click="addSpecSelect"
          >添加规格</el-button
        >
      </div>
    </div>
    <el-empty v-if="!skuList.length" description="请添加规格" />

    <!-- 规格添加表 start -->
    <div
      style="border: 1px solid #dcdfe6; border-top: none; position: relative"
      v-for="(item, index) in skuList"
      :key="index"
    >
      <i
        v-show="index !== 0"
        style="position: absolute; right: 10px; top: 10px"
        class="el-icon-close"
        @click="deleteSpecSelect(item)"
      ></i>

      <el-form ref="specForm" :model="specFormData" label-width="100px">
        <el-form-item
          class="pt-20"
          label="规格名称："
          :rules="[{ required: true, message: '请选择规格名称', trigger: 'blur' }]"
        >
          <el-select placeholder="请选择规格名称" v-model="item.name">
            <el-option
              v-for="option in skuSelectList"
              :key="option.id"
              :label="option.name"
              :disabled="skuList.find(el => el.name === option.name) ? true : false"
              :value="option.name"
            />
          </el-select>
        </el-form-item>

        <el-form-item
          label="规格值："
          :rules="[{ required: true, message: '请输入规格值', trigger: 'blur' }]"
        >
          <el-col
            v-for="(spec, specIndex) in item.item"
            :key="spec.id"
            class="ml-10"
            style="position: relative"
            :span="4"
          >
            <el-input
              placeholder="请输入规格值"
              v-model="spec.value"
              @blur="editSpec(index, specIndex, spec)"
            />
            <i
              v-show="item.item.length > 1"
              class="el-icon-error"
              style="position: absolute; top: -2px; right: -5px"
              @click="deleteSpec(item, spec)"
            ></i>
          </el-col>
          <el-button class="ml-10" type="text" @click="addSpec(item)">添加规格值</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 规格添加表 end -->

    <!-- sku表格 start -->
    <el-form class="skuForm" ref="skuForm" :model="formData">
      <el-table class="mt-30" :data="formData.skuList" :span-method="arraySpanMethod">
        <!-- 固定选择值 -->
        <el-table-column
          :label="skuList[0].name"
          align="center"
          prop="specOneValue"
        ></el-table-column>
        <el-table-column
          v-if="skuList.length > 1"
          :label="skuList[1].name"
          align="center"
          prop="specTwoValue"
        ></el-table-column>

        <el-table-column align="center" width="90" prop="mainGraph">
          <template slot="header">
            <div>
              <span style="color: #f56c6c">*</span>
              <span>图片</span>
            </div>
          </template>
          <template slot-scope="scope">
            <el-form-item label="" :prop="'skuList.' + scope.$index + '.mainGraph'">
              <upload-image
                :isShowTip="false"
                :lazy="true"
                :file-type="['jpg', 'png', 'jpeg']"
                file-pixel="120*120"
                :file-size="1"
                :size="70"
                v-model="scope.row.mainGraph"
              />
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column align="center" prop="price">
          <template slot="header">
            <div>
              <span style="color: #f56c6c">*</span>
              <span>兑换积分</span>
            </div>
          </template>
          <template slot-scope="scope">
            <el-form-item
              label=""
              :prop="'skuList.' + scope.$index + '.price'"
              :rules="rules.price"
            >
              <el-input
                :maxlength="6"
                :disabled="!scope.row.state"
                v-model.number="scope.row.price"
                placeholder=""
              ></el-input>
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column align="center" prop="costPrice">
          <template slot="header">
            <div>
              <span style="color: #f56c6c">*</span>
              <span>成本价</span>
            </div>
          </template>
          <template slot-scope="scope">
            <el-form-item
              label=""
              :prop="'skuList.' + scope.$index + '.costPrice'"
              :rules="rules.costPrice"
            >
              <el-input :disabled="!scope.row.state" v-model="scope.row.costPrice"></el-input>
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column align="center" prop="weight">
          <template slot="header">
            <div>
              <span style="color: #f56c6c">*</span>
              <span>重量（kg）</span>
            </div>
          </template>
          <template slot-scope="scope">
            <el-form-item :prop="'skuList.' + scope.$index + '.weight'" :rules="rules.weight">
              <el-input
                :disabled="!scope.row.state"
                v-model="scope.row.weight"
                placeholder=""
              ></el-input>
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column align="center" prop="code">
          <template slot="header">
            <div>
              <span style="color: #f56c6c">*</span>
              <span>规格编码</span>
            </div>
          </template>
          <template slot-scope="scope">
            <el-form-item label="" :prop="'skuList.' + scope.$index + '.code'" :rules="rules.code">
              <el-input
                :maxlength="15"
                :disabled="!scope.row.state"
                v-model="scope.row.code"
              ></el-input>
            </el-form-item>
          </template>
        </el-table-column>

        <el-table-column align="center" prop="stockQuantity">
          <template slot="header">
            <div>
              <span style="color: #f56c6c">*</span>
              <span>库存</span>
            </div>
          </template>
          <template slot-scope="scope">
            <el-form-item
              :prop="'skuList.' + scope.$index + '.stockQuantity'"
              :rules="rules.stockQuantity"
            >
              <el-input
                :disabled="!scope.row.state"
                v-model.number="scope.row.stockQuantity"
              ></el-input>
            </el-form-item>
          </template>
        </el-table-column>

        <el-table-column label="货物状态" align="center" prop="state">
          <template slot-scope="scope">
            <el-form-item label="" :prop="'skuList.' + scope.$index + '.state'">
              <el-checkbox :value="!scope.row.state" @change="changeSkuState(scope.row, $event)"
                >缺货</el-checkbox
              >
            </el-form-item>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
    <!-- sku表格 end -->

    <!-- 批量设置 start -->
    <div class="flex justify-between mt-20">
      <!-- 设置值 -->
      <div class="flex align-center">
        <span class="text-bold">批量设置：</span>
        <el-link
          class="mr-10"
          :underline="false"
          v-for="item in volumeSetList"
          :key="item.key"
          :type="currentSet === item.key ? 'primary' : ''"
          @click="currentSet = item.key"
          >{{ item.label }}</el-link
        >
      </div>

      <div class="flex">
        <el-input
          v-model="volumeSetValue"
          clearable
          :maxlength="15"
          placeholder="请输入批量值"
        ></el-input>
        <el-button class="ml-10" @click="cancleVolumeSet">取消</el-button>
        <el-button type="primary" @click="confirmVolumeSet">确定</el-button>
      </div>
    </div>
    <!-- 批量设置 end -->
  </div>
</template>

<script>
import { useGenerateUUID } from '@/hooks/index'
export default {
  name: 'SelectSku',
  components: {},
  props: {
    // 规格值选择列表
    skuSelectList: Array
  },
  data() {
    // 积分值自定义表单验证
    const pricePass = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请输入积分值'))
      } else if (value < 0 || value > 200000) {
        callback(new Error('请输入0-200000之间数值'))
      } else {
        callback()
      }
    }

    // 重量自定义表单验证
    const weightPass = (rule, value, callback) => {
      let regx = /^([0-9]|[1-9]\d|100)(\.\d{1,2})?$/
      if (value == 0 || !regx.test(value) || value > 100) {
        callback(new Error('请输入0-100不为0的数，保留两位小数'))
      } else {
        callback()
      }
    }

    // 商品编码自定义校验
    const codePass = (rule, value, callback) => {
      let regx = /^[A-Za-z0-9\-]{1,15}$/
      if (!regx.test(value)) {
        callback(new Error('英文、数字或"-"符号'))
      } else {
        callback()
      }
    }

    return {
      // 当前批量设置值字段
      currentSet: 'price',
      // 批量设置值
      volumeSetValue: '',
      // 规格值表单
      specFormData: {},
      // 表单
      formData: {
        skuList: []
      },
      rules: {
        price: [
          { required: true, type: 'number', message: '请输入数字', trigger: 'blur' },
          { validator: pricePass, trigger: ['change', 'blur'] }
        ],
        weight: [
          { required: true, message: '请输入重量', trigger: 'blur' },
          { required: true, validator: weightPass, trigger: 'blur' }
        ],
        code: [
          {
            required: true,
            message: '请输入商品编码',
            validator: codePass,
            trigger: 'blur'
          }
        ],
        stockQuantity: [
          {
            required: true,
            message: '请输入库存',
            trigger: 'blur'
          },
          {
            pattern: /^[1-9]{1}\d{0,6}$/,
            message: '库存在1-9999999之间',
            trigger: 'blur'
          }
        ],
        costPrice: [
          { required: true, message: '请输入成本价', trigger: 'blur' },
          {
            pattern: /^((0(?=\.))|([1-9]\d{0,6})|1000000)(\.\d{1,2})?$/,
            message: '成本价在0.1-1000000之间'
          }
        ]
      },

      // 规格值列表
      skuList: [
        {
          id: useGenerateUUID(),
          name: '',
          item: [{ value: '', id: useGenerateUUID() }],
          prop: 'specOneValue'
        }
      ],

      // 规格生成列表
      skuResList: [],
      // 规格表格合并行数组，与skuResList相对应
      mergeIndexList: []
    }
  },
  created() {
    // console.log(this.type, this.spuId)
    // 渲染生成sku列表
    this.renderSkuList(true)
  },
  computed: {
    // 批量设置列表
    volumeSetList() {
      const arr = [
        {
          label: '兑换积分',
          key: 'price'
        },
        {
          label: '成本价',
          key: 'costPrice'
        },
        {
          label: '库存',
          key: 'stockQuantity'
        },
        {
          label: '重量',
          key: 'weight'
        },
        {
          label: '规则编码',
          key: 'code'
        }
      ]
      return arr
    }
  },
  methods: {
    // 验证spuid
    async validSupId(row) {
      try {
        await this.$http.supply.valid({
          params: { goodsSupply: 'JUHE', skuId: row.supplySkuId, spuId: this.spuId }
        })
        // console.log(res)
      } catch (error) {
        this.formData.skuList = this.formData.skuList.map(el => {
          if (el.id === row.id) {
            return { ...el, supplySkuId: '', supplyState: false }
          }
          return { ...el }
        })
      }
    },

    // 添加下拉规格
    addSpecSelect() {
      if (this.skuList.length >= 2) return
      const item = {
        id: useGenerateUUID(),
        name: '',
        item: [{ value: '', id: useGenerateUUID() }],
        prop: this.skuList.length >= 1 ? 'specTwoValue' : 'specOneValue'
      }
      this.skuList.push(item)
    },

    // 删除整体规格值
    deleteSpecSelect(item) {
      this.skuList = this.skuList.filter(el => el.id !== item.id)
      this.renderSkuList(false)
    },

    // 添加规格值
    addSpec(item) {
      // console.log(item)
      this.skuList = this.skuList.map(el => {
        const newEl = this.$lodash.cloneDeep(el)
        if (newEl.id === item.id) {
          newEl.item.push({ value: '', id: useGenerateUUID() })
        }
        return newEl
      })
      this.renderSkuList(false)
    },

    // 修改规格值
    editSpec(index, specIndex, spec) {
      this.renderSkuList()
      const fileName = index === 0 ? 'specOneValue' : 'specTwoValue'
      // 是否存在相同项
      const isRepeat = this.skuList[index].item.filter(el => el.value === spec.value)
      if (isRepeat.length > 1) {
        this.$message.error('已存在改规格值')
      }
      // 修改sku结果列表
      this.formData.skuList = this.formData.skuList.map(el => {
        const newEl = this.$lodash.cloneDeep(el)
        const attrSetIndex = newEl.attrSet.findIndex(item => item.specItemId === spec.id)
        if (attrSetIndex !== -1) {
          newEl.attrSet[attrSetIndex].value = spec.value
          newEl[fileName] = spec.value
        }
        return newEl
      })
      this.createTempMergeIndex()
    },

    // 删除规格值
    deleteSpec(parentItem, specItem) {
      this.skuList = this.skuList.map(el => {
        const newEl = this.$lodash.cloneDeep(el)
        if (newEl.id === parentItem.id) {
          newEl.item = newEl.item.filter(item => item.id !== specItem.id)
        }
        return newEl
      })
      this.renderSkuList(false)
    },

    // 修改sku货物状态
    changeSkuState(row, flag) {
      // console.log(row, flag)
      this.formData.skuList = this.formData.skuList.map(el => {
        if (el.cusId === row.cusId) {
          return { ...el, state: !flag }
        } else {
          return { ...el }
        }
      })
    },

    // 生成合并行结果
    createTempMergeIndex() {
      // 处理arr，生成一个与行数相同的数组记录每一行设置的合并数
      const skuList = this.formData.skuList
      const tempMergeIndex = []
      let posIndex = null
      for (let i = 0; i < skuList.length; i++) {
        if (i === 0) {
          tempMergeIndex.push(1)
          posIndex = 0
        } else {
          if (skuList[i].specOneValue && skuList[i].specOneValue === skuList[i - 1].specOneValue) {
            tempMergeIndex[posIndex] += 1
            tempMergeIndex.push(0)
          } else {
            tempMergeIndex.push(1)
            posIndex = i
          }
        }
      }
      // console.log('tempMergeIndex', tempMergeIndex)
      this.mergeIndexList = tempMergeIndex
    },

    /**
     * 行合并
     * 当前行row
     * 当前列column
     * 当前行号rowIndex
     * 当前列号columnIndex
     */
    arraySpanMethod({ row, column, rowIndex, columnIndex }) {
      // console.log(row, column, rowIndex, columnIndex)
      if (columnIndex == 0) {
        return {
          rowspan: this.mergeIndexList[rowIndex],
          colspan: 1
        }
      }
    },

    // 生成sku列表
    renderSkuList(init) {
      const skuList = [] //收集结果
      let cusId = 0 //生成skuId
      // 旧的SkuList转map，方便下方的复用判断
      const prevSkuMap = this.skuList2Map(init ? [] : this.formData.skuList)
      // console.log('---------------------------')
      // console.log('prevSkuMap', prevSkuMap)

      const loop = (rowIndex, prevOptions) => {
        const attrItem = this.skuList[rowIndex]
        if (attrItem.item.length === 0) {
          loop(rowIndex + 1, prevOptions)
          return
        }
        for (const option of attrItem.item) {
          const curOptions = prevOptions.concat({
            label: attrItem.name,
            value: option.value,
            specItemId: option.id
          })
          if (rowIndex === this.skuList.length - 1) {
            //判断如果是最后一层，那就是组合完整了，将结果收集到全局的容器里
            cusId++
            const key = curOptions.map(({ specItemId }) => specItemId).join('_') // 将sku的选项值用'_'连接起来组成一个key
            if (prevSkuMap[key]) {
              // console.log('存在已有数据', prevSkuMap[key])
              // // 如果改变前后的sku key相同，复用sku数据,避免数据覆盖
              skuList.push({
                ...prevSkuMap[key],
                cusId: `${cusId}`
              })
            } else {
              // console.log('key存在变动')
              let pre = null
              if (curOptions.length > 1) {
                // 规格值从一条变成两条
                pre = prevSkuMap[key.split('_')[0]]
              } else {
                // 规格值从两条变成一条
                pre = Object.entries(prevSkuMap).filter(el => el[0].split('_')[0] === key)[0]?.[1]
                // console.log('待处理pre', pre)
              }
              // console.log('curOptions', curOptions)
              let sku = {
                cusId: `${cusId}`,
                key,
                attrSet: curOptions,
                specOneValue: curOptions[0]['value'] ?? '',
                specTwoValue: curOptions?.[1]?.['value'] ?? '',
                mainGraph: '',
                price: '',
                costPrice: '',
                weight: '',
                code: '',
                stockQuantity: '',
                // true-有货 false-缺货
                state: true
              }
              // 是否能够在规格条数发生变化后找到相同值
              if (pre) {
                delete pre.attrSet
                delete pre.cusId
                delete pre.key
                // console.log('key变动后相同项', pre)
                sku = Object.assign(sku, pre)
                if (sku.attrSet.length === 1) {
                  sku.specTwoValue = ''
                }
              }
              if (!sku.specTwoValue) delete sku.specTwoValue
              skuList.push(sku)
            }
          } else {
            // 递归调用
            loop(rowIndex + 1, curOptions)
          }
        }
      }
      loop(0, [])
      this.formData.skuList = skuList
      console.log(skuList)
      // return skuList
      // 表格合并数组生成
      this.createTempMergeIndex()
    },

    // 生成sku列表重复map
    skuList2Map(skuList) {
      return skuList.reduce((map, sku) => {
        map[sku.key] = sku
        return map
      }, {})
    },

    // 点击取消批量设置
    cancleVolumeSet() {
      this.volumeSetValue = ''
      this.currentSet = 'price'
    },

    // 批量设置sku值
    confirmVolumeSet() {
      if (!this.volumeSetValue) {
        this.$message.error('请输入批量值')
        return
      }
      let value = this.volumeSetValue
      // 表单验证

      if (this.currentSet === 'price') {
        if (!/^\d+$/.test(value)) {
          return this.$message.error('请输入数字')
        }
        if (value < 0 || value > 200000) {
          return this.$message.error('兑换积分设置区间为0-200000')
        }
      }

      // 校验库存
      let regxStock = /^[1-9]{1}\d{0,6}$/
      if (this.currentSet === 'stockQuantity' && !regxStock.test(value)) {
        this.$message.error('库存在1-9999999之间')
        return
      }

      // 校验成本价
      let regxConstPrice = /^((0(?=\.))|([1-9]\d{0,6})|1000000)(\.\d{1,2})?$/
      if (this.currentSet === 'costPrice' && !regxConstPrice.test(value)) {
        this.$message.error('成本价在0.1-1000000之间')
        return
      }

      // 校验重量
      let regxWeight = /^([0-9]|[1-9]\d|100)(\.\d{1,2})?$/
      if (this.currentSet === 'weight' && (value == 0 || !regxWeight.test(value) || value > 100)) {
        this.$message.error('重量设置区间为0-100，且不为0的数')
        return
      }

      // 校验规则编码
      if (this.currentSet === 'code' && !/^[A-Za-z0-9\-]{1,15}$/.test(value)) {
        this.$message.error("请输入15位以内数字英文或者'-'符号组成的规则编码")
        return
      }

      // 批量设置
      this.formData.skuList = this.formData.skuList.map(el => ({
        ...el,
        [this.currentSet]: value
      }))
    }
  }
}
</script>

<style lang="scss" scoped>
/deep/.ele-upload-image,
/deep/.el-upload--picture-card {
  width: 70px !important;
  height: 70px !important;
  margin-bottom: 0;
}
.skuForm {
  /deep/ .el-form-item__content {
    max-width: 150px;
    position: static !important;
    .el-input {
      max-width: 150px;
      position: relative;
    }
    .el-form-item__error {
      left: 10px;
      top: auto;
    }
  }
  /deep/ .el-table__cell {
    padding: 15px 0 !important;
  }
}
</style>
